// Copyright Epic Games, Inc. All Rights Reserved.

#include "Feedback/ContextEffects/LyraContextEffectsLibrary.h"

#include "NiagaraSystem.h"
#include "Sound/SoundBase.h"

#include UE_INLINE_GENERATED_CPP_BY_NAME(LyraContextEffectsLibrary)


/**
 * 获取效果
 */
void ULyraContextEffectsLibrary::GetEffects(const FGameplayTag Effect, const FGameplayTagContainer Context, 
	TArray<USoundBase*>& Sounds, TArray<UNiagaraSystem*>& NiagaraSystems)
{
	// 确保效果有效且库已加载
	if (Effect.IsValid() && Context.IsValid() && EffectsLoadState == EContextEffectsLibraryLoadState::Loaded) // 检查效果和上下文有效性及加载状态
	{
		// 循环遍历上下文效果
		for (const auto& ActiveContextEffect : ActiveContextEffects) // 遍历活动上下文效果
		{
			// 确保效果是精确标签匹配，并确保上下文具有效果中的所有标签（并且两者都为空或都不为空）
			if (Effect.MatchesTagExact(ActiveContextEffect->EffectTag) // 效果精确匹配
				&& Context.HasAllExact(ActiveContextEffect->Context) // 上下文具有所有精确标签
				&& (ActiveContextEffect->Context.IsEmpty() == Context.IsEmpty())) // 上下文空状态一致
			{
				// 获取所有匹配的声音和Niagara系统
				Sounds.Append(ActiveContextEffect->Sounds); // 追加声音
				NiagaraSystems.Append(ActiveContextEffect->NiagaraSystems); // 追加Niagara系统
			}
		}
	}
}

/**
 * 加载效果
 */
void ULyraContextEffectsLibrary::LoadEffects()
{
	// 如果当前未加载，加载效果到库
	if (EffectsLoadState != EContextEffectsLibraryLoadState::Loading) // 检查是否不在加载中
	{
		// 设置加载状态为加载中
		EffectsLoadState = EContextEffectsLibraryLoadState::Loading; // 设置加载状态

		// 清除任何旧的活动效果
		ActiveContextEffects.Empty(); // 清空活动上下文效果

		// 调用内部加载函数
		LoadEffectsInternal(); // 内部加载效果
	}
}

/**
 * 获取上下文效果库加载状态
 */
EContextEffectsLibraryLoadState ULyraContextEffectsLibrary::GetContextEffectsLibraryLoadState()
{
	// 返回当前加载状态
	return EffectsLoadState; // 返回效果加载状态
}

/**
 * 内部加载效果
 */
void ULyraContextEffectsLibrary::LoadEffectsInternal()
{
	// TODO 添加库的异步加载

	// 为异步加载复制数据
	TArray<FLyraContextEffects> LocalContextEffects = ContextEffects; // 本地上下文效果

	// 准备活动上下文效果数组
	TArray<ULyraActiveContextEffects*> ActiveContextEffectsArray; // 活动上下文效果数组

	// 循环遍历上下文效果
	for (const FLyraContextEffects& ContextEffect : LocalContextEffects) // 遍历本地上下文效果
	{
		// 确保标签有效
		if (ContextEffect.EffectTag.IsValid() && ContextEffect.Context.IsValid()) // 检查效果标签和上下文有效性
		{
			// 创建新的活动上下文效果
			ULyraActiveContextEffects* NewActiveContextEffects = NewObject<ULyraActiveContextEffects>(this); // 创建新活动上下文效果

			// 传递相关标签数据
			NewActiveContextEffects->EffectTag = ContextEffect.EffectTag; // 设置效果标签
			NewActiveContextEffects->Context = ContextEffect.Context; // 设置上下文

			// 尝试加载并添加效果到新活动上下文效果
			for (const FSoftObjectPath& Effect : ContextEffect.Effects) // 遍历效果
			{
				if (UObject* Object = Effect.TryLoad()) // 尝试加载对象
				{
					if (Object->IsA(USoundBase::StaticClass())) // 如果是声音基类
					{
						if (USoundBase* SoundBase = Cast<USoundBase>(Object)) // 转换为声音基类
						{
							NewActiveContextEffects->Sounds.Add(SoundBase); // 添加到声音数组
						}
					}
					else if (Object->IsA(UNiagaraSystem::StaticClass())) // 如果是Niagara系统类
					{
						if (UNiagaraSystem* NiagaraSystem = Cast<UNiagaraSystem>(Object)) // 转换为Niagara系统
						{
							NewActiveContextEffects->NiagaraSystems.Add(NiagaraSystem); // 添加到Niagara系统数组
						}
					}
				}
			}

			// 添加新活动上下文到活动上下文效果数组
			ActiveContextEffectsArray.Add(NewActiveContextEffects); // 添加到活动上下文效果数组
		}
	}

	// TODO 异步加载后调用加载完成
	// 标记加载完成
	this->LyraContextEffectLibraryLoadingComplete(ActiveContextEffectsArray); // 调用加载完成
}

/**
 * Lyra上下文效果库加载完成
 */
void ULyraContextEffectsLibrary::LyraContextEffectLibraryLoadingComplete(
	TArray<ULyraActiveContextEffects*> LyraActiveContextEffects)
{
	// 标记数据为已加载
	EffectsLoadState = EContextEffectsLibraryLoadState::Loaded; // 设置加载状态为已加载

	// 将传入的上下文效果数组追加到当前活动上下文效果列表
	ActiveContextEffects.Append(LyraActiveContextEffects); // 追加活动上下文效果
}